<template>
	<view class="custom-picker-container">
		<view class="mask" v-if="show" @click="onMaskClick"></view>
		<view class="picker-popup" :class="{ show: show }" :style="{ height: height + 'px' }">
			<view class="picker-header" :style="{ backgroundColor: themeColor }">
				<view class="header-btn cancel" :style="{ color: cancelColor }" @click="onCancel">
					取消
				</view>
				<view class="header-title" :style="{ color: titleColor }">{{ title }}</view>
				<view
					class="header-btn confirm"
					:style="{ color: confirmColor }"
					@click="onConfirm"
				>
					确定
				</view>
			</view>
			<view class="picker-content">
				<picker-view
					:value="selectedIndex"
					@change="onChange"
					:indicator-style="indicatorStyle"
					:mask-style="maskStyle"
					:immediate-change="immediateChange"
					class="picker-view"
				>
					<picker-view-column>
						<view
							class="picker-item"
							:style="{ color: itemColor }"
							v-for="(item, index) in options"
							:key="index"
						>
							{{ item[labelKey] }}
						</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>
	</view>
</template>

<script>
/**
 * 自定义底部弹出选择器组件
 * @example
 * <template>
 *   <view>
 *     <button @click="showPicker = true">打开选择器</button>
 *     <custom-picker
 *       v-model:show="showPicker"
 *       :options="pickerOptions"
 *       title="请选择城市"
 *       :height="300"
 *       @confirm="onConfirm"
 *       @cancel="onCancel"
 *     />
 *   </view>
 * </template>
 *
 * 选项数组，格式：[{label: '显示文本', value: '值'}]
 *
 * @property {Boolean} show - 控制选择器显示/隐藏，支持v-model:show
 * @property {Array} options - 选项数组，格式：[{label: '显示文本', value: '值'}]
 * @property {Number} defaultIndex - 默认选中项的索引
 * @property {String} labelKey - 选项对象中用于显示的键名，默认'label'
 * @property {String} valueKey - 选项对象中用于值的键名，默认'value'
 * @property {Boolean} immediateChange - 是否立即触发change事件
 * @property {String} themeColor - 主题颜色，默认'#FFFFFF'
 * @property {String} title - 标题文字，默认'请选择'
 * @property {Number|String} height - 弹出层高度，默认500
 * @property {Boolean} maskClosable - 是否点击蒙层关闭，默认true
 * @property {String} cancelColor - 取消按钮颜色，默认'#333333'
 * @property {String} confirmColor - 确认按钮颜色，默认'#333333'
 * @property {String} titleColor - 标题颜色，默认'#333333'
 * @property {String} itemColor - 选项文字颜色，默认'#333333'
 *
 * @event {Function} confirm - 点击确认按钮时触发，参数：{index, item, value}
 * @event {Function} cancel - 点击取消按钮时触发
 * @event {Function} change - 选择改变时触发（当immediateChange为true时），参数：{index, item, value}
 */
export default {
	name: "CustomPicker",
	props: {
		// 是否显示选择器
		show: {
			type: Boolean,
			default: false
		},
		// 选项数组
		options: {
			type: Array,
			default: () => []
		},
		// 默认选中项的索引
		defaultIndex: {
			type: Number,
			default: 0
		},
		// 选项对象中用于显示的键名
		labelKey: {
			type: String,
			default: "label"
		},
		// 选项对象中用于值的键名
		valueKey: {
			type: String,
			default: "value"
		},
		// 是否立即触发change事件
		immediateChange: {
			type: Boolean,
			default: false
		},
		// 指示器样式
		indicatorStyle: {
			type: String,
			default: "height: 50px;"
		},
		// 蒙层样式
		maskStyle: {
			type: String,
			default:
				"background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6)), linear-gradient(0deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6));"
		},
		// 弹出层高度
		height: {
			type: [Number, String],
			default: 500
		},
		// 主题颜色
		themeColor: {
			type: String,
			default: "#FFFFFF"
		},
		// 标题
		title: {
			type: String,
			default: "请选择"
		},
		// 是否点击蒙层关闭
		maskClosable: {
			type: Boolean,
			default: true
		},
		// 取消按钮颜色
		cancelColor: {
			type: String,
			default: "#333333"
		},
		// 确认按钮颜色
		confirmColor: {
			type: String,
			default: "#333333"
		},
		// 标题颜色
		titleColor: {
			type: String,
			default: "#333333"
		},
		// 选项文字颜色
		itemColor: {
			type: String,
			default: "#333333"
		}
	},
	data() {
		return {
			selectedIndex: [this.defaultIndex],
			tempIndex: [this.defaultIndex]
		}
	},
	methods: {
		onChange(e) {
			const index = e.detail.value[0]
			this.tempIndex = [index]
			if (this.immediateChange) {
				this.selectedIndex = [index]
				this.$emit("change", {
					index,
					item: this.options[index],
					value: this.options[index][this.valueKey]
				})
			}
		},
		onCancel() {
			this.$emit("cancel")
			this.$emit("update:show", false)
		},
		onConfirm() {
			this.selectedIndex = this.tempIndex
			const index = this.tempIndex[0]
			this.$emit("confirm", {
				index,
				item: this.options[index],
				value: this.options[index][this.valueKey]
			})
			this.$emit("update:show", false)
		},
		onMaskClick() {
			if (this.maskClosable) {
				this.onCancel()
			}
		}
	}
}
</script>

<style lang="scss" scoped>
.custom-picker-container {
	.mask {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.4);
		z-index: 999;
	}

	.picker-popup {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: #fff;
		transform: translateY(100%);
		transition: transform 0.3s ease-out;
		z-index: 1000;

		&.show {
			transform: translateY(0);
		}

		.picker-header {
			display: flex;
			align-items: center;
			justify-content: space-between;
			height: 90rpx;
			padding: 0 30rpx;

			.header-btn {
				font-size: 28rpx;
				padding: 10rpx 20rpx;
			}

			.header-title {
				font-size: 32rpx;
				font-weight: 500;
			}
		}

		.picker-content {
			height: calc(100% - 90rpx);

			.picker-view {
				width: 100%;
				height: 100%;
			}

			.picker-item {
				line-height: 50px;
				text-align: center;
				font-size: 28rpx;
			}
		}
	}
}
</style>
